package com.zmh.service.httpclient;

import java.io.IOException;
import java.net.Inet4Address;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.w3c.dom.Attr;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mysql.cj.core.exceptions.CJConnectionFeatureNotAvailableException;
import com.zmh.common.DateUtil;
import com.zmh.dao.BookDao;
import com.zmh.dao.BookFavDao;
import com.zmh.dao.BookLinkDao;
import com.zmh.dao.CatalogDao;
import com.zmh.model.book.BookFav;
import com.zmh.model.book.BookInfo;
import com.zmh.model.book.CatalogInfo;
import com.zmh.model.httpclient.HttpHeader;

/**
 * @author zhoumh
 * @version 创建时间：2017年7月19日 下午4:31:12
 * @Description  还是要做修改，多次调用，获取所有链接，做302跳转之后的地址
 */
@Service
public class BookUpdate {
	private static Logger logger = LoggerFactory.getLogger(BookUpdate.class);
	@Autowired
	private BookDao bookDao;
	@Autowired
	private CatalogDao catalogDao;
	@Autowired
	private HttpConnectionManager httpConnectionManager;
	private static CloseableHttpClient httpClient = null;
	private static CloseableHttpResponse response = null; 
	private Header[] headers = null ;
	private static HttpClientContext httpContext = HttpClientContext.create();
	@PostConstruct
	public void init(){
		getHttpClient();
	}
	@PreDestroy  
    public void  dostory(){  
		closeHttpClient();
	}
	
	/**
	 * 起点书籍目录获取
	 * @author zhoumh
	 * @version 创建时间：2017年9月20日 下午3:13:53
	 */
	public void qidian(BookInfo bookinfo) {
		String html = getHTML(bookinfo.getCatalog());
//		Document doc = Jsoup.parse(html);
		JSONObject js = JSON.parseObject(html);
		JSONArray vs = js.getJSONObject("data").getJSONArray("vs");
		for(int i=1 ; i<vs.size() ; i++){
			JSONArray cs = vs.getJSONObject(i).getJSONArray("cs");
			for(int j=1 ; j<cs.size() ; j++){
				JSONObject catalog = cs.getJSONObject(j);
				CatalogInfo catalogInfo = new CatalogInfo();
				catalogInfo.setBid(bookinfo.getUuid());
				catalogInfo.setName(catalog.getString("cN"));
				catalogInfo.setUtime(catalog.getString("uT"));
				catalogInfo.setCount(catalog.getInteger("cnt"));
				catalogInfo.setSort(catalog.getInteger("uuid"));
				catalogInfo.setDescription(catalog.getString("id"));
				// 判断该章节是否已存在
				int rs = catalogDao.insCatalogByExi(catalogInfo);
				if (rs==1) {
					logger.info(bookinfo.getName()+" 更新章节："+JSON.toJSONString(catalogInfo));
				}
			}
		}
	}
	
	/**
	 * 磨铁书籍目录获取
	 * @param bookinfo 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月18日 上午10:05:55 
	 * @Description:
	 */
	public void motie(BookInfo bookinfo) {
		String html = getHTML(bookinfo.getCatalog());
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("div.catebg").select("a[href^=/book/86369]");
		for (Element el : chapters) {
			CatalogInfo catalogInfo = new CatalogInfo();
			catalogInfo.setBid(bookinfo.getUuid());
			catalogInfo.setName(el.select("span.chapter_name").text());
			catalogInfo.setUtime(el.attr("data-time"));
			catalogInfo.setCount(0);
			String url = el.attr("href");
			String id = url.substring(url.lastIndexOf("_")+1,url.length());
			catalogInfo.setSort(Integer.parseInt(id));
			catalogInfo.setDescription(id);
			// 判断该章节是否已存在
			int rs = catalogDao.insCatalogByExi(catalogInfo);
//			logger.info(""+JSON.toJSONString(catalogInfo));
			if (rs==1) {
				logger.info(bookinfo.getName()+" 更新章节："+JSON.toJSONString(catalogInfo));
			}
		}
	}
	/**
	 * 创世书籍目录获取
	 * @param bookinfo 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月18日 上午10:05:55 
	 * @Description:
	 */
	public void chuangshi(BookInfo bookinfo) {
		String html = getHTML(bookinfo.getCatalog());
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("div.catebg").select("a[href^=/book]");
		for (Element el : chapters) {
			CatalogInfo catalogInfo = new CatalogInfo();
			catalogInfo.setBid(bookinfo.getUuid());
			catalogInfo.setName(el.select("span.chapter_name").text());
			catalogInfo.setUtime(el.attr("data-time"));
			catalogInfo.setCount(0);
			String url = el.attr("href");
			String id = url.substring(url.lastIndexOf("_")+1,url.length());
			catalogInfo.setSort(Integer.parseInt(id));
			catalogInfo.setDescription(id);
			// 判断该章节是否已存在
			int rs = catalogDao.insCatalogByExi(catalogInfo);
			if (rs==1) {
				logger.info(bookinfo.getName()+" 更新章节："+JSON.toJSONString(catalogInfo));
			}
		}
	}
	/**
	 * 纵横书籍目录获取
	 * @param bookinfo 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月18日 上午10:05:55 
	 * @Description:
	 */
	public void zongheng(BookInfo bookinfo) {
		headers = HttpHeader.custom()
				.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36")
				.build();
		String html = getHTML(bookinfo.getCatalog());
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("div#chapterListPanel").select("td.chapterBean");
		for (Element el : chapters) {
			CatalogInfo catalogInfo = new CatalogInfo();
			catalogInfo.setBid(bookinfo.getUuid());
			catalogInfo.setName(el.attr("chapterName"));
			String utime = DateUtil.convertDateTimesByms(Long.parseLong(el.attr("updateTime")));
			catalogInfo.setUtime(utime);
			catalogInfo.setCount(Integer.parseInt(el.attr("wordNum")));
			String id = el.attr("chapterId");
			catalogInfo.setSort(Integer.parseInt(id));
			catalogInfo.setDescription(id);
			// 判断该章节是否已存在
			int rs = catalogDao.insCatalogByExi(catalogInfo);
			if (rs==1) {
				logger.info(bookinfo.getName()+" 更新章节："+JSON.toJSONString(catalogInfo));
			}
		}
	}
	/**
	 * 掌阅书籍目录获取
	 * @param bookinfo 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月18日 上午10:05:55 
	 * @Description:
	 */
	public void ireader(BookInfo bookinfo) {
		String html = getHTML(bookinfo.getCatalog());
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("div.fL_con").select("a[href^=/book]");
		for (Element el : chapters) {
			CatalogInfo catalogInfo = new CatalogInfo();
			catalogInfo.setBid(bookinfo.getUuid());
			catalogInfo.setName(el.text());
			catalogInfo.setUtime(DateUtil.getDateTime());
			String[] url = el.attr("href").split("/");
			String id = url[3];
			catalogInfo.setSort(Integer.parseInt(id));
			catalogInfo.setDescription(id);
			// 判断该章节是否已存在
			int rs = catalogDao.insCatalogByExi(catalogInfo);
			if (rs==1) {
				logger.info(bookinfo.getName()+" 更新章节："+JSON.toJSONString(catalogInfo));
			}
		}
	}
	/**
	 * 神起书籍目录获取
	 * @param bookinfo 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月18日 上午10:05:55 
	 * @Description:
	 */
	public void shenqiwang(BookInfo bookinfo) {
		String html = getHTML(bookinfo.getCatalog());
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("ul#j-choose-volume").select("a.f-text-overflow");
		for (Element el : chapters) {
			CatalogInfo catalogInfo = new CatalogInfo();
			catalogInfo.setBid(bookinfo.getUuid());
			catalogInfo.setName(el.text());
			catalogInfo.setUtime(el.attr("data-time"));
			String onclick = el.attr("onclick");
			String id = onclick.substring(onclick.indexOf(",")+2,onclick.lastIndexOf("")-1);
			catalogInfo.setSort(Integer.parseInt(id));
			catalogInfo.setDescription(id);
			// 判断该章节是否已存在
			int rs = catalogDao.insCatalogByExi(catalogInfo);
			if (rs==1) {
				logger.info(bookinfo.getName()+" 更新章节："+JSON.toJSONString(catalogInfo));
			}
		}
	}
	/**
	 * 塔读书籍目录获取
	 * @param bookinfo 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月18日 上午10:05:55 
	 * @Description:
	 */
	public void tadu(BookInfo bookinfo) {
		headers = HttpHeader.custom()
				.host("www.tadu.com")
				.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36")
				.build();
		String html = getHTML(bookinfo.getCatalog());
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("div.detail-chapters").select("a[href^=/book]");
		for (Element el : chapters) {
			CatalogInfo catalogInfo = new CatalogInfo();
			catalogInfo.setBid(bookinfo.getUuid());
			catalogInfo.setName(el.text());
			String temp = el.attr("title");
			String utime = temp.substring(temp.indexOf("-")-4,temp.indexOf(":")+3)+":00";
			catalogInfo.setUtime(utime);
			String[] id = el.attr("href").split("/");
			catalogInfo.setSort(Integer.parseInt(id[3]));
			catalogInfo.setDescription(id[3]);
			catalogInfo.setCount(Integer.parseInt(temp.substring(temp.lastIndexOf(":")+3,temp.length())));
			// 判断该章节是否已存在
			int rs = catalogDao.insCatalogByExi(catalogInfo);
			if (rs==1) {
				logger.info(bookinfo.getName()+" 更新章节："+JSON.toJSONString(catalogInfo));
			}
		}
	}
	/**
	 * 查询笔趣阁5200指定页面是否存在指定章节
	 * @param catalogUrl
	 * @param catalogName 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月27日 下午8:40:40 
	 * @Description:
	 */
	public String bqg5200(String catalogUrl,String catalogName) {
		String result = "";
		String html = getHTMLByGBK(catalogUrl);
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("div#readerlist>ul>li");
		for (Element el : chapters) {
			String name = el.select("a[href^=/xiaoshuo]").text();
			if (catalogName.equals(name)) {
				result = "http://www.bqg5200.com"+el.select("a[href^=/xiaoshuo]").attr("href");
				logger.info("笔趣阁5200更新章节："+catalogName+" "+result);
				// 发现更新立即返回
				return result;
			}
		}
		return result;
	}
	/**
	 * 查询百书库指定页面是否存在指定章节
	 * @param catalogUrl
	 * @param catalogName 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月27日 下午8:40:40 
	 * @Description:
	 */
	public String baishuku(String catalogUrl,String catalogName) {
		String result = "";
		String html = getHTMLByGBK(catalogUrl);
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("td.ccss>a");
		for (Element el : chapters) {
			String name = el.text();
			if (catalogName.equals(name)) {
				result = catalogUrl+el.attr("href");
				logger.info("百书库更新章节："+catalogName+" "+result);
				return result;
			}
		}
		return result;
	}
	
	/**
	 * 查询醋溜儿文学指定页面是否存在指定章节
	 * @param catalogUrl
	 * @param catalogName 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月27日 下午8:40:40 
	 * @Description:
	 */
	public String clewx(String catalogUrl,String catalogName) {
		String result = "";
		String html = getHTML(catalogUrl);
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("div.bottom>div.con>dl>dd");
		for (Element el : chapters) {
			String name = el.select("a[href^=http]").text();
			if (catalogName.equals(name)) {
				result = el.select("a[href^=http]").attr("href");
				logger.info("醋溜儿文学更新章节："+catalogName+" "+result);
				return result;
			}
		}
		return result;
	}
	
	/**
	 * 查询笔趣阁5200指定页面是否存在指定章节
	 * @param catalogUrl
	 * @param catalogName 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月27日 下午8:40:40 
	 * @Description:
	 */
	public String biquge5200(String catalogUrl,String catalogName) {
		headers = HttpHeader.custom()
				.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36")
				.build();
		String result = "";
		String html = getHTML(catalogUrl);
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("dl>dd");
		for (Element el : chapters) {
			String name = el.select("a[href^=http]").text();
			if (catalogName.equals(name)) {
				result = el.select("a[href^=http]").attr("href");
				logger.info("笔趣阁5200更新章节："+catalogName+" "+result);
				return result;
			}
		}
		return result;
	}
	/**
	 * 查询笔趣看指定页面是否存在指定章节
	 * @param catalogUrl
	 * @param catalogName 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月27日 下午8:40:40 
	 * @Description:
	 */
	public String biqukan(String catalogUrl,String catalogName) {
		headers = HttpHeader.custom()
				.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36")
				.build();
		String result = "";
		String html = getHTML(catalogUrl);
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("dl>dd");
		for (Element el : chapters) {
			String name = el.select("a").text();
			if (catalogName.equals(name)) {
				result = "http://www.biqukan.com"+el.select("a").attr("href");
				logger.info("笔趣看更新章节："+catalogName+" "+result);
				return result;
			}
		}
		return result;
	}
	
	/**
	 * 查询三江阁指定页面是否存在指定章节
	 * @param catalogUrl
	 * @param catalogName 
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年11月27日 下午8:40:40 
	 * @Description:
	 */
	public String sanjiangge(String catalogUrl,String catalogName) {
		headers = HttpHeader.custom()
				.userAgent("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36")
				.build();
		String result = "";
		String html = getHTMLByGBK(catalogUrl);
		Document doc = Jsoup.parse(html);
		Elements chapters = doc.select("dl>dd");
		for (Element el : chapters) {
			String name = el.select("a").text();
			if (catalogName.equals(name)) {
				result = catalogUrl.replace("index.html", "")+el.select("a").attr("href");
				logger.info("三江阁更新章节："+catalogName+" "+result);
				return result;
			}
		}
		return result;
	}
	/** 
	 * 根据URL发起请求并返回请求结果
	 * @param url 请求链接
	 * @author zhoumh
	 * @version 创建时间：2017年10月13日 上午10:30:47
	 */
	private String getHTML(String url) {
		String html = "";
		try {
			response = doGet(url);
			HttpEntity entity = response.getEntity();
			// 判断返回实体是否为空
			if (entity != null) {
				// 获取返回的内容
				html = EntityUtils.toString(entity, "UTF-8");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
		headers = HttpHeader.custom().build();
		return html;
	}
	/** 
	 * 根据URL发起请求并返回请求结果
	 * @param url 请求链接
	 * @author zhoumh
	 * @version 创建时间：2017年10月13日 上午10:30:47
	 */
	private String getHTMLByGBK(String url) {
		String html = "";
		try {
			response = doGet(url);
			HttpEntity entity = response.getEntity();
			// 判断返回实体是否为空
			if (entity != null) {
				// 获取返回的内容
				html = EntityUtils.toString(entity, "GBK");
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
		headers = HttpHeader.custom().build();
		return html;
	}
	/**
	 * 根据传入的URL和httpclient发起get请求并返回结果
	 * @param url 请求的地址
	 * @throws ClientProtocolException
	 * @throws IOException 
	 * @return: CloseableHttpResponse
	 * @author: zhoumh
	 * @version: 创建时间：2017年10月17日 上午11:04:45 
	 * @Description:
	 */
	private CloseableHttpResponse doGet(String url)
			throws ClientProtocolException, IOException {
		HttpGet httpGet = new HttpGet(url);
		httpGet.setHeaders(headers);
		// 接收返回信息
		response = getHttpClient().execute(httpGet, httpContext);
		return response;
	}
	/**
	 * 根据传入的URL和httpclient发起POST请求并返回结果
	 * @param url 请求的地址
	 * @param uefEntity 请求的表单
	 * @throws ClientProtocolException
	 * @throws IOException 
	 * @return: CloseableHttpResponse
	 * @author: zhoumh
	 * @version: 创建时间：2017年7月26日 下午5:19:23
	 * @Description: 尝试超时捕捉并切换url重试
	 */
	private CloseableHttpResponse doPost(String url, UrlEncodedFormEntity uefEntity)
			throws ClientProtocolException, IOException {
		// Post请求
		HttpPost httppost = new HttpPost(url);
		httppost.setEntity(uefEntity);
		// 发送请求并接收返回信息
		response = getHttpClient().execute(httppost,httpContext);
		return response;
	}
	/**
	 * 从连接池获取httpclient
	 * @return: CloseableHttpClient
	 * @author: zhoumh
	 * @version: 创建时间：2017年10月17日 上午9:45:28 
	 * @Description:
	 */
	private CloseableHttpClient getHttpClient(){
		if (httpClient==null) {
			httpClient = httpConnectionManager.getHttpsClient();
		}
		return httpClient;
	}
	/**
	 * 关闭httpclient
	 * @return: void
	 * @author: zhoumh
	 * @version: 创建时间：2017年10月17日 上午9:45:50 
	 * @Description:
	 */
	private void closeHttpClient(){
		try {
			if (response != null) {
				response.close();
			}
			if (httpClient != null) {
				httpClient.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	
	/**
	 * 从书籍源站获取书籍更新
	 * @author zhoumh
	 * @version 创建时间：2017年10月8日 下午4:35:03
	 */
//	public List<BookInfo> getBookUpd() {
//		//连载的书籍列表
//		List<BookInfo> updbooks = bookDao.selBooksByStatus("0");
//		// 获取存储的最新书架信息根据用户UUID
//		for (BookInfo bookinfo : updbooks) {
//			System.out.println(JSON.toJSONString(bookinfo));
//			// 获取每本书籍的目录页地址
//			String catalog = bookinfo.getCatalog();
//			// 根据站点信息调用不同的更新方法，暂时写死调用
//			if (StringUtils.isEmpty(catalog)) {
//				//书籍没有目录页
//				continue;
//			}
//			if (catalog.indexOf("qidian")>0) {
//				qidian(bookinfo);
//			}
//			if (catalog.indexOf("motie")>0) {
//				motie(bookinfo);
//			}
//			if (catalog.indexOf("zongheng")>0) {
//				zongheng(bookinfo);
//			}
//			if (catalog.indexOf("tadu")>0) {
//				tadu(bookinfo);
//			}
//			if (catalog.indexOf("shenqiwang")>0) {
//				shenqiwang(bookinfo);
//			}
//			if (catalog.indexOf("ireader")>0) {
//				ireader(bookinfo);
//			}
//		}
//		//到此为止直接返回待通知列表，然后交给上级业务类调用微信服务接口发给用户
////		logger.info(JSON.toJSONString(updateFavs));
////		System.out.println(html);
//		return updbooks;
//	}
}
